﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace DevelopAssistant.Core
{
    public class CommandRunner
    {
        private string _sqltext;
        public string SqlText
        {
            get
            {
                return _sqltext;
            }
            set
            {
                _sqltext = value;
                if (!string.IsNullOrEmpty(_sqltext))
                {
                    this.CommandBatch = CommandBatch.Parse(_sqltext);
                }
            }
        }
        public DateTime BeginTime { get; set; }
        public DateTime EndTime { get; set; }
        public CommandResult Result { get; set; }
        public CommandBatch CommandBatch
        {
            private set;
            get;
        }
        public CommandTypes CommandType { get; set; }
        public CommandRunner()
        {
            this.CommandType = CommandTypes.Execute;
            this.Result = new CommandResult();
        }

    }

    public class CommandResult
    {
        public Boolean Success { get; set; }
        public String Message { get; set; }
        public CommandResultCallBack CallBack { get; set; }
    }

    public class CommandBatch
    {
        private static IEnumerable<string> SplitByBatchIndecator(string script, string batchIndicator)
        {
            string pattern = string.Concat("^\\s*", batchIndicator, "\\s*$");
            RegexOptions options = RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline;

            foreach (string batch in Regex.Split(script, pattern, options))
            {
                yield return batch.Trim();
            }
        }

        public List<CommandText> CommandList { get; set; }

        public CommandBatch(string SqlText)
        {
            CommandList = new List<CommandText>();
        }        

        public void Add(CommandText Command)
        {
            CommandList.Add(Command);
        }

        public static CommandBatch Parse(string SqlText)
        {
            CommandBatch commandBatch = new CommandBatch(SqlText);
            foreach (string sqlPart in SplitByBatchIndecator(SqlText, "GO").Where(sqlPart => !string.IsNullOrEmpty(sqlPart)))
            {
                commandBatch.CommandList.Add(new CommandText(sqlPart));
            }
            return commandBatch;             
        }

    }

    public class CommandText
    {
        public string Text { get; set; }

        public CommandText(string text)
        {
            this.Text = text;
        }
    }

    public delegate void CommandResultCallBack(object sender,bool commit);

    public enum CommandTypes
    {
        Commit,
        Rollback,
        Execute
    }
}
